package top.kaoshanji.q1ch05a;

import org.hamcrest.Matchers;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.servlet.view.InternalResourceView;
import top.kaoshanji.q1ch05a.dao.SpittleRepository;
import top.kaoshanji.q1ch05a.model.Spittle;
import top.kaoshanji.q1ch05a.web.SpittleController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author kaoshanji
 * ^_^
 * create time 2025/4/24 14:20
 */
public class SpittleControllerTest {

    /**
     * 代码清单test-q1ch05a-149页a：测试对SpittleController处理针对"/spittle/spittleList"的GET请求
     * @throws Exception Exception
     */
    @Test
    public void testSpittleList() throws Exception {
        List<Spittle> expectedSpittles = createSpittleList(20);
        SpittleRepository mockRepository = Mockito.mock(SpittleRepository.class);

        Mockito.when(mockRepository.findSpittles(Long.MAX_VALUE, 20)).thenReturn(expectedSpittles);

        SpittleController controller = new SpittleController(mockRepository);
        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).
                setSingleView(new InternalResourceView("/WEB-INF/views/spittleListPage.jsp")).build();

        mockMvc.perform(MockMvcRequestBuilders.get("/spittle/spittleList"))
                .andExpect(MockMvcResultMatchers.view().name("spittleListPage"))
                .andExpect(MockMvcResultMatchers.model().attributeExists("spittleList"))
                .andExpect(MockMvcResultMatchers.model().attribute("spittleList", Matchers.hasItems(expectedSpittles.toArray())));

    }

    /**
     * 代码清单test-q1ch05a-154页a：用来测试分页Spittle列表的新方法
     * @throws Exception
     */
    @Test
    public void testSpittleListPaged() throws Exception {
        List<Spittle> expectedSpittles = createSpittleList(50);
        SpittleRepository mockRepository = Mockito.mock(SpittleRepository.class);

        Mockito.when(mockRepository.findSpittles(238900, 50)).thenReturn(expectedSpittles);

        SpittleController controller = new SpittleController(mockRepository);
        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).
                setSingleView(new InternalResourceView("/WEB-INF/views/spittleListPage.jsp")).build();

        mockMvc.perform(MockMvcRequestBuilders.get("/spittle/spittleList?max=238900&count=50"))
                .andExpect(MockMvcResultMatchers.view().name("spittleListPage"))
                .andExpect(MockMvcResultMatchers.model().attributeExists("spittleList"))
                .andExpect(MockMvcResultMatchers.model().attribute("spittleList", Matchers.hasItems(expectedSpittles.toArray())));

    }

    /**
     * 代码清单test-q1ch05a-156页a：测试对某个Spittle的请求，其中ID要在路径变量中指定
     */
    @Test
    public void testSpittleDetail() throws Exception {
        Spittle expectedSpittle = new Spittle("Hello", new Date());
        SpittleRepository mockRepository = Mockito.mock(SpittleRepository.class);

        Mockito.when(mockRepository.findOne(3)).thenReturn(expectedSpittle);

        SpittleController controller = new SpittleController(mockRepository);
        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).build();

        mockMvc.perform(MockMvcRequestBuilders.get("/spittle/spittleDetail/3"))
                .andExpect(MockMvcResultMatchers.view().name("spittleDetailPage"))
                .andExpect(MockMvcResultMatchers.model().attributeExists("spittle"))
                .andExpect(MockMvcResultMatchers.model().attribute("spittle", expectedSpittle));

    }




    private List<Spittle> createSpittleList(int count) {
        List<Spittle> spittleList = new ArrayList<Spittle>();
        for (int i=0; i < count; i++) {
            spittleList.add(new Spittle("Spittle " + i, new Date()));
        }
        return spittleList;
    }

}
